/*
 * Copyright (C) 2025 Tsingteng MicroSystem
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "nfa_hci_api.h"
#include "hci_cmd.h"
#include "hci_defs.h"
#include "hci_session.h"
#include "nci_module.h"
#include "nfc_log_api.h"
#include "hci_transport.h"
#include "hci_event_dispatch.h"
#include "data_int.h"
#include "nci_feature.h"

/**
 * @brief HCI模块入口
 */
#if IS_FEATURE_ON(NCI_FEATURE_HCI)

static tNCI_STATUS nfa_hci_init(const tNCI_MODULE_INIT_CFG *p_cfg) {
    (void) p_cfg;
    tNCI_STATUS status;
    NFCLOG_I("%s enter..", __func__);
    tNCI_DATA_CHANNEL *hci_channel = nci_data_find_channel(NCI_DATA_CHANNEL_HCI);
    if (NULL == hci_channel) {
        NFCLOG_E("hci channel not found");
        return NCI_STATUS_EXT_FAILED;
    }
    status = hci_transport_init();
    if (NCI_STATUS_OK != status) {
        NFCLOG_E("hci transport init failed ret:%d", status);
        return status;
    }
    status = hci_event_dispatcher_init();
    if (NCI_STATUS_OK != status) {
        NFCLOG_E("hci event dispatcher init failed ret:%d", status);
        return status;
    }
    status = hci_session_init();
    if ((NCI_STATUS_OK != status) && (NCI_STATUS_EXT_ALREADY_OPENED != status)) {
        NFCLOG_E("hci session init failed, ret:%d", status);
        return status;
    }
    // status = hci_cmd_adm_clear_all_pipe(); // for debug, 触发走全量初始化流程
    status = hci_init_all_pipe((NCI_STATUS_EXT_ALREADY_OPENED != status));
    if (NCI_STATUS_OK != status) {
        NFCLOG_E("hci init pipes failed ret:%d", status);
        return status;
    }
    hci_session_dump();

    return NCI_STATUS_OK;
}

static tNCI_STATUS nfa_hci_deinit(bool is_shutdown) {
    (void) is_shutdown;
    tNCI_STATUS status;
    NFCLOG_I("%s enter..", __func__);
    status = hci_session_deinit();
    if (NCI_STATUS_OK != status) {
        NFCLOG_E("hci session deinit ret:%d", status);
    }
    status = hci_event_dispatcher_deinit();
    if (NCI_STATUS_OK != status) {
        NFCLOG_E("hci event dispatcher deinit failed ret:%d", status);
    }
    status = hci_transport_deinit();
    if (NCI_STATUS_OK != status) {
        NFCLOG_E("hci transport deinit ret:%d", status);
    }
    return status;
}

/**
 * @brief 处理远端EE发送过来的指令
 * @param pipe      cmd来源的pipe
 * @param ins       指令值
 * @param data      指令参数
 * @param data_len  指令参数长度
 */
void hci_handle_remote_cmd(uint8_t pipe, uint8_t ins, const uint8_t *data, uint16_t data_len) {
    uint8_t rsp = HCI_RSP_ANY_E_CMD_NOT_SUPPORT;
    uint8_t *rsp_data = NULL;
    uint16_t rsp_data_len = 0;
    NFCLOG_D("pipe:%02X ins:%02X data_len:%d", pipe, ins, data_len);
    if (HCI_STATIC_PIPE_ADMIN == pipe) {
        switch (ins) {
        // 目前还不会收到create 和 delete pipe指令，暂不处理
        // case HCI_INS_ADM_CREATE_PIPE:
        //case HCI_INS_ADM_DELETE_PIPE:
        case HCI_INS_ADM_NOTIFY_PIPE_CREATED:
            if (5 == data_len) {
                hci_session_add_pipe(data[4], data[3], data[0], data[1], false);
                rsp = HCI_RSP_ANY_OK;
            } else {
                NFCLOG_E("invalid param of ADM_NOTIFY_PIPE_CREATE");
                rsp = HCI_RSP_ANY_E_CMD_PAR_UNKNOWN;
            }
            goto exit;
        case HCI_INS_ADM_NOTIFY_PIPE_DELETED:
            if (1 == data_len) {
                hci_session_delete_pipe(data[0]);
                rsp = HCI_RSP_ANY_OK;
            } else {
                NFCLOG_E("invalid param of ADM_NOTIFY_PIPE_DELETED");
                rsp = HCI_RSP_ANY_E_CMD_PAR_UNKNOWN;
            }
            goto exit;
        case HCI_INS_ADM_NOTIFY_ALL_PIPE_CLEARED:
            if (1 == data_len) {
                hci_session_clear_pipes_on_ee(data[0]);
                rsp = HCI_RSP_ANY_OK;
            } else {
                NFCLOG_E("invalid param of ADM_NOTIFY_ALL_PIPE_CLEARED");
                rsp = HCI_RSP_ANY_E_CMD_PAR_UNKNOWN;
            }
            goto exit;
        default:
            break;
        }
    }
    switch (ins) {
    case HCI_INS_ANY_OPEN_PIPE:
        if (0 == data_len) {
            hci_session_update_pipe_status(pipe, true);
            rsp = HCI_RSP_ANY_OK;
            rsp_data = osi_malloc(1);
            if (NULL == rsp_data) {
                NFCLOG_E("malloc for open pipe rsp failed");
                rsp = HCI_RSP_ANY_E_NOK;
            } else {
                rsp_data[0] = 0; // 此gate上已经打开的pipe数量
            }
        } else {
            rsp = HCI_RSP_ANY_E_CMD_PAR_UNKNOWN;
        }
        break;
    case HCI_INS_ANY_CLOSE_PIPE:
        if (0 == data_len) {
            hci_session_update_pipe_status(pipe, false);
            rsp = HCI_RSP_ANY_OK;
        } else {
            rsp = HCI_RSP_ANY_E_CMD_PAR_UNKNOWN;
        }
        break;
    default:
        // 其他指令暂不支持
        break;
    }

exit:
    hci_send_hcp_message_async(pipe, HCI_HCP_TYPE_RSP, rsp, rsp_data_len, rsp_data);
    if (rsp_data) {
        osi_free(rsp_data);
        rsp_data = NULL;
    }
}

tNCI_MODULE g_hci_manager = {
    .name = "HCI_MANAGER",
    .state = NCI_MODULE_STATE_DISABLED,
    .init = nfa_hci_init,
    .deinit = nfa_hci_deinit,
};

#endif // IS_FEATURE_ON(NCI_FEATURE_HCI)
